from fastapi import APIRouter, Depends
from schema.resp import RestfulModel
from schema.resp.drive_action_screen import MapInfo, UserNum, UserNumTendency, RenterMark, RenterComplaint, ComplaintTendency, RuleViolation, UserFeedback
from dependencies import get_mongo_db, require_login
from typing import List
from pymongo.database import Database
import utils
from random import randint
import hashlib
from datetime import datetime, timedelta, date


drive_action_perception_router = APIRouter(prefix='/driver-behavior/screen',
                                           tags=['驾驶行为感知-大屏'])


class MongoCollectionName:
    """
    mongo 中 collection 的 name 常量
    """
    MAP_INFO = 'drive_action_map_info'
    USER_NAME = 'drive_action_user_num'
    RENTER_MARK = 'drive_action_renter_mark'
    RENTER_COMPLAINT = 'drive_action_renter_complaint'
    COMPLAINT_TENDENCY = 'drive_action_complaint_tendency'
    RULE_VIOLATION = 'drive_action_rule_violation'
    VIOLATION_RANK = 'drive_action_violation_rank'
    USER_FEEDBACK = 'drive_action_user_feedback'


@drive_action_perception_router.get('/map-info',
                                    response_model=RestfulModel[List[MapInfo]],
                                    summary='地图信息')
async def get_map_info(mongo_db: Database = Depends(get_mongo_db)):
    map_info_col = mongo_db[MongoCollectionName.MAP_INFO]
    cursor = map_info_col.find()
    result = [post_process_map_info(MapInfo(address=doc['address'], loc=doc['loc'])) for doc in cursor]
    return RestfulModel.success(result)


def post_process_map_info(map_info: MapInfo) -> MapInfo:
    if map_info.address in {'北京市', '武汉市'}:
        map_info.loc.append(randint(75, 85))
    else:
        map_info.loc.append(randint(5, 30))
    return map_info


@drive_action_perception_router.get('/user-num',
                                    response_model=RestfulModel[List[UserNum]],
                                    summary='用户数')
async def get_user_num(mongo_db: Database = Depends(get_mongo_db)):
    mongo_col = mongo_db[MongoCollectionName.USER_NAME]
    query_doc = mongo_col.find_one()
    result = UserNum(value=query_doc['user_num'])
    return RestfulModel.success([result])


@drive_action_perception_router.get('/user-num-tendency',
                                    response_model=RestfulModel[List[UserNumTendency]],
                                    summary='用户人数趋势')
async def get_user_num_tendency():
    now = datetime.now()
    today = date(now.year, now.month, now.day)
    delta = timedelta(days=1)
    result = []
    num = 2469559
    for i in range(7):
        t = today - i * delta
        user_num_tendency = UserNumTendency(
            time=t,
            value=num
        )
        result.append(user_num_tendency)
        rand_val = int.from_bytes(hashlib.md5(str(t).encode()).digest(), byteorder='big') % 200 + 100
        num -= rand_val
    result.reverse()
    return RestfulModel.success(result)


@drive_action_perception_router.get('/renter-mark',
                                    response_model=RestfulModel[List[RenterMark]],
                                    summary='用户评价表')
async def get_renter_mark(mongo_db: Database = Depends(get_mongo_db)):
    mongo_col = mongo_db[MongoCollectionName.RENTER_MARK]
    cursor = mongo_col.find()
    fields = ['content', 'star', 'create_time', 'driver_name']
    result = [
        RenterMark(**utils.bean_map(doc, fields))
        for doc in cursor
    ]
    return RestfulModel.success(result)


@drive_action_perception_router.get('/renter-complaint',
                                    response_model=RestfulModel[List[RenterComplaint]],
                                    summary='用户投诉表')
async def get_renter_complaint(mongo_db: Database = Depends(get_mongo_db)):
    mongo_col = mongo_db[MongoCollectionName.RENTER_COMPLAINT]
    cursor = mongo_col.find()
    fields = ['update_time', 'driver_name', 'reason', 'all_code_name']
    result = [
        RenterComplaint(**utils.bean_map(doc, fields)) for doc in cursor
    ]
    return RestfulModel.success(result)


@drive_action_perception_router.get('/complaint-tendency',
                                    response_model=RestfulModel[List[ComplaintTendency]],
                                    summary='投诉趋势')
async def get_complaint_tendency(mongo_db: Database = Depends(get_mongo_db)):
    mongo_col = mongo_db[MongoCollectionName.COMPLAINT_TENDENCY]
    cursor = mongo_col.find()
    state_map = ['待处理', '处理中', '已处理', '处理']
    result = [
        post_process_complaint_tendency(ComplaintTendency(begin_time=doc['begin_time'], end_time=doc['end_time'], state=state_map[doc['state']]))
        for doc in cursor
    ]
    return RestfulModel.success(result)


def post_process_complaint_tendency(complaint_tendency: ComplaintTendency) -> ComplaintTendency:
    hash_val = int.from_bytes(hashlib.md5((str(complaint_tendency.end_time.date()) + complaint_tendency.state).encode()).digest(), byteorder='big') % 500
    complaint_tendency.count = hash_val
    return complaint_tendency


@drive_action_perception_router.get('/violation-show',
                                    response_model=RestfulModel[List[RuleViolation]],
                                    summary='违章信息展示')
async def get_violation_show(mongo_db: Database = Depends(get_mongo_db)):
    mongo_col = mongo_db[MongoCollectionName.RULE_VIOLATION]
    cursor = mongo_col.find()
    fields = ['description', 'address', 'amount', 'create_time', 'nature']
    result = [
        RuleViolation(**utils.bean_map(doc, fields)) for doc in cursor
    ]
    return RestfulModel.success(result)


@drive_action_perception_router.get('/violation-rank',
                                    response_model=RestfulModel[List[RuleViolation]],
                                    summary='违章排名')
async def get_violation_rank(mongo_db: Database = Depends(get_mongo_db)):
    mongo_col = mongo_db[MongoCollectionName.VIOLATION_RANK]
    cursor = mongo_col.find()
    fields = ['description', 'address', 'amount', 'create_time', 'nature']
    result = [
        RuleViolation(**utils.bean_map(doc, fields)) for doc in cursor
    ]
    result = sorted(result, key=lambda rule_violation: rule_violation.amount)
    return RestfulModel.success(result)


@drive_action_perception_router.get('/user-feedback',
                                    response_model=RestfulModel[List[UserFeedback]],
                                    summary='异常驾驶行为')
async def get_user_feedback(mongo_db: Database = Depends(get_mongo_db)):
    mongo_col = mongo_db[MongoCollectionName.USER_FEEDBACK]
    cursor = mongo_col.find()
    fields = ['user_type', 'content', 'time', 'name']
    result = [
        UserFeedback(**utils.bean_map(doc, fields)) for doc in cursor
    ]
    return RestfulModel.success(result)
